package pl.edu.mimuw.irs.core.model.design.net;

import java.beans.PropertyChangeListener;
import java.util.List;
import java.util.Set;

import pl.edu.mimuw.irs.core.model.design.atomic.AtomicSubnet;
import pl.edu.mimuw.irs.core.model.petrinet.INode;
import pl.edu.mimuw.irs.core.util.Position;

/**
 * @author Jakub Rauch
 * Created on: 2009-05-09
 */
public interface IRSNode extends INode {

	// *** Properties
	
	public static final String FRAGMENTATION = "Fragmentation";
	public static final String EXPANDED = "Expanded";
	public static final String VISIBLE = "Visible";
	
	// *** Attributes

	// Getters and setters
	public NodeType getNodeType();
	public void setNodeType(NodeType nodeType);
	public Fragmentation getFragmentation();
	public void setFragmentation(Fragmentation fragmentation);
	public IRSNode getParent();
	public void setParent(IRSNode parent);
	public Position getSuperPosition();
	public Position getCustomPosition();
	public void setCustomPosition(Position position);
	public List<IRSNode> getChildren();
	/*
	 * This method assumes, that children are in proper structure for the fragmentation.
	 * Because of that this function should be used only for setting copied parameters from
	 * other nodes of the same type.
	 * @param children
	 * @param fragmentation
	 */
	public void setChildren(List<IRSNode> children, Fragmentation fragmentation);
	public void addChild(IRSNode node);
	public void addChild(int i, IRSNode node);
	public void removeChild(IRSNode node);
	public List<IRSNode> getInputDescendants();
	public List<IRSNode> getOutputDescendants();
	public boolean isAtomic();
	public AtomicSubnet getAtomicWorkflow(AtomicSubnet subnet);
	public List<IRSArc> getAtomicIncomingArcs();
	public List<IRSArc> getAtomicOutgoingArcs();
	public boolean isAncestorOf(IRSNode node);
	
	// Useful for graphical tool
	public Set<Fragmentation> getSupportedFragmentations();
	public boolean isExpanded();
	public void setExpanded(boolean expand);
	public void addPropertyChangeListener(PropertyChangeListener listener);
	public void removePropertyChangeListener(PropertyChangeListener listener);
	
	// *** Methods
	
	/**
	 * Checks if this node is a root - has no parents.
	 */
	public boolean isRoot();

	/**
	 * Returns all leaf nodes from this one.
	 */
	public List<IRSNode> getAtomicNodes();
	
	/**
	 * Returns non expanded descendants of expanded nodes or self.
	 */
	public List<IRSNode> getExpandedNodes();
	
	/**
	 * Creates copy of this node and all descendants as well as arcs between them.
	 * @return copied node
	 */
	public IRSNode copy();
	
	/**
	 * Creates copy of this node and all descendants as well as arcs between them.
	 * @return copied node
	 */
	public IRSNodeCopier getCopier();
	
	/*
	 * Creates copy of this node - only a clean copy of this
	 * node for the atomic subnet purposes. The data
	 * will be attached to the copied node in getAtomicSubnet() method.
	 * This method should be protected but is made public to force
	 * its creation on every node.
	 * @return copied node
	 */
	public INode copy(AtomicSubnet subnet);
	
	// *** Enums
	
	/**
	 * Type of node (activity, normal transition,...) - used to distinguish nodes
	 * in IRSWorkflow. Distinguished nodes can be efficiently managed. 
	 */
	public enum NodeType {
		TRANSITION,
		ACTIVITY,
		PLACE,
		RESOURCE;
	}

}
